{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-03-09T13:23:17.434447Z",
     "start_time": "2022-03-09T13:23:17.427466Z"
    }
   },
   "outputs": [],
   "source": [
    "from tensorflow import keras\n",
    "import tensorflow as tf\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-03-09T13:23:17.813434Z",
     "start_time": "2022-03-09T13:23:17.435445Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(5000, 28, 28) (5000,)\n",
      "(55000, 28, 28) (55000,)\n",
      "(10000, 28, 28) (10000,)\n"
     ]
    }
   ],
   "source": [
    "fashion_mnist = keras.datasets.fashion_mnist\n",
    "(x_train_all, y_train_all), (x_test, y_test) = fashion_mnist.load_data()\n",
    "x_valid, x_train = x_train_all[:5000], x_train_all[5000:]\n",
    "y_valid, y_train = y_train_all[:5000], y_train_all[5000:]\n",
    "\n",
    "print(x_valid.shape, y_valid.shape)\n",
    "print(x_train.shape, y_train.shape)\n",
    "print(x_test.shape, y_test.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-03-09T13:23:18.813296Z",
     "start_time": "2022-03-09T13:23:17.814431Z"
    }
   },
   "outputs": [],
   "source": [
    "# 标准化\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "\n",
    "scaler = StandardScaler()\n",
    "x_train_scaled = scaler.fit_transform(\n",
    "    x_train.astype(np.float32).reshape(-1, 1)).reshape(-1, 28, 28, 1)\n",
    "x_valid_scaled = scaler.transform(\n",
    "    x_valid.astype(np.float32).reshape(-1, 1)).reshape(-1, 28, 28, 1)\n",
    "\n",
    "x_test_scaled = scaler.transform(\n",
    "    x_test.astype(np.float32).reshape(-1, 1)).reshape(-1, 28, 28, 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-03-09T13:23:18.828255Z",
     "start_time": "2022-03-09T13:23:18.814292Z"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "def make_dataset(data, target, epochs, batch_size, shuffle=True):\n",
    "    dataset = tf.data.Dataset.from_tensor_slices((data, target))\n",
    "    if shuffle:\n",
    "        dataset = dataset.shuffle(10000)\n",
    "    dataset = dataset.repeat(epochs).batch(batch_size).prefetch(50)\n",
    "    return dataset\n",
    "\n",
    "batch_size = 64\n",
    "epochs = 20\n",
    "train_dataset = make_dataset(x_train_scaled, y_train, epochs, batch_size)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-03-09T13:26:32.186760Z",
     "start_time": "2022-03-09T13:26:32.076056Z"
    }
   },
   "outputs": [],
   "source": [
    "model = keras.models.Sequential()\n",
    "# 卷积\n",
    "model.add(keras.layers.Conv2D(filters = 32, \n",
    "                              kernel_size = 3, \n",
    "                              padding = 'same',\n",
    "                              activation='relu',\n",
    "                              # batch_size, height, width, channels\n",
    "                              input_shape=(28, 28, 1))) # (28, 28, 32)\n",
    "\n",
    "model.add(keras.layers.Conv2D(filters = 32, \n",
    "                              kernel_size = 3, \n",
    "                              padding = 'same',\n",
    "                              activation='relu'))\n",
    "# 池化\n",
    "model.add(keras.layers.MaxPool2D()) # (14, 14, 32)\n",
    "\n",
    "model.add(keras.layers.Conv2D(filters = 64, \n",
    "                              kernel_size = 3, \n",
    "                              padding = 'same',\n",
    "                              activation='relu')) # (14, 14, 64)\n",
    "model.add(keras.layers.Conv2D(filters = 64, \n",
    "                              kernel_size = 3, \n",
    "                              padding = 'same',\n",
    "                              activation='relu'))\n",
    "# 池化\n",
    "model.add(keras.layers.MaxPool2D()) # (7, 7, 64)\n",
    "model.add(keras.layers.Conv2D(filters = 128, \n",
    "                              kernel_size = 3, \n",
    "                              padding = 'same',\n",
    "                              activation='relu')) # (7, 7, 128)\n",
    "model.add(keras.layers.Conv2D(filters = 128, \n",
    "                              kernel_size = 3, \n",
    "                              padding = 'same',\n",
    "                              activation='relu')) # (7, 7, 128)\n",
    "# 池化, 向下取整\n",
    "model.add(keras.layers.MaxPooling2D()) # (3, 3, 128)\n",
    "\n",
    "model.add(keras.layers.Flatten())\n",
    "model.add(keras.layers.Dense(512, activation='relu'))\n",
    "model.add(keras.layers.Dense(256, activation='relu'))\n",
    "model.add(keras.layers.Dense(10, activation='softmax'))\n",
    "\n",
    "model.compile(loss='sparse_categorical_crossentropy',\n",
    "             optimizer='adam',\n",
    "             metrics=['accuracy'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-03-09T13:26:38.177883Z",
     "start_time": "2022-03-09T13:26:38.163920Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model: \"sequential_3\"\n",
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "conv2d_9 (Conv2D)            (None, 28, 28, 32)        320       \n",
      "_________________________________________________________________\n",
      "conv2d_10 (Conv2D)           (None, 28, 28, 32)        9248      \n",
      "_________________________________________________________________\n",
      "max_pooling2d_9 (MaxPooling2 (None, 14, 14, 32)        0         \n",
      "_________________________________________________________________\n",
      "conv2d_11 (Conv2D)           (None, 14, 14, 64)        18496     \n",
      "_________________________________________________________________\n",
      "conv2d_12 (Conv2D)           (None, 14, 14, 64)        36928     \n",
      "_________________________________________________________________\n",
      "max_pooling2d_10 (MaxPooling (None, 7, 7, 64)          0         \n",
      "_________________________________________________________________\n",
      "conv2d_13 (Conv2D)           (None, 7, 7, 128)         73856     \n",
      "_________________________________________________________________\n",
      "conv2d_14 (Conv2D)           (None, 7, 7, 128)         147584    \n",
      "_________________________________________________________________\n",
      "max_pooling2d_11 (MaxPooling (None, 3, 3, 128)         0         \n",
      "_________________________________________________________________\n",
      "flatten_3 (Flatten)          (None, 1152)              0         \n",
      "_________________________________________________________________\n",
      "dense_9 (Dense)              (None, 512)               590336    \n",
      "_________________________________________________________________\n",
      "dense_10 (Dense)             (None, 256)               131328    \n",
      "_________________________________________________________________\n",
      "dense_11 (Dense)             (None, 10)                2570      \n",
      "=================================================================\n",
      "Total params: 1,010,666\n",
      "Trainable params: 1,010,666\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "model.summary()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-03-09T13:26:53.498734Z",
     "start_time": "2022-03-09T13:26:53.482776Z"
    }
   },
   "outputs": [],
   "source": [
    "eval_dataset = make_dataset(x_valid_scaled, y_valid, epochs=1, batch_size=32, shuffle=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-03-09T13:28:07.239241Z",
     "start_time": "2022-03-09T13:26:53.818400Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/10\n",
      "859/859 [==============================] - 8s 8ms/step - loss: 0.6733 - accuracy: 0.7513 - val_loss: 0.2870 - val_accuracy: 0.8928\n",
      "Epoch 2/10\n",
      "859/859 [==============================] - 7s 8ms/step - loss: 0.2779 - accuracy: 0.8975 - val_loss: 0.2417 - val_accuracy: 0.9102\n",
      "Epoch 3/10\n",
      "859/859 [==============================] - 7s 8ms/step - loss: 0.2268 - accuracy: 0.9187 - val_loss: 0.2514 - val_accuracy: 0.9062\n",
      "Epoch 4/10\n",
      "859/859 [==============================] - 7s 8ms/step - loss: 0.1920 - accuracy: 0.9299 - val_loss: 0.2413 - val_accuracy: 0.9124\n",
      "Epoch 5/10\n",
      "859/859 [==============================] - 7s 8ms/step - loss: 0.1706 - accuracy: 0.9366 - val_loss: 0.2133 - val_accuracy: 0.9210\n",
      "Epoch 6/10\n",
      "859/859 [==============================] - 7s 8ms/step - loss: 0.1516 - accuracy: 0.9439 - val_loss: 0.2106 - val_accuracy: 0.9250\n",
      "Epoch 7/10\n",
      "859/859 [==============================] - 7s 8ms/step - loss: 0.1279 - accuracy: 0.9522 - val_loss: 0.2371 - val_accuracy: 0.9214\n",
      "Epoch 8/10\n",
      "859/859 [==============================] - 7s 9ms/step - loss: 0.1186 - accuracy: 0.9550 - val_loss: 0.2560 - val_accuracy: 0.9222\n",
      "Epoch 9/10\n",
      "859/859 [==============================] - 7s 9ms/step - loss: 0.1036 - accuracy: 0.9623 - val_loss: 0.2754 - val_accuracy: 0.9176\n",
      "Epoch 10/10\n",
      "859/859 [==============================] - 7s 8ms/step - loss: 0.1007 - accuracy: 0.9637 - val_loss: 0.2578 - val_accuracy: 0.9318\n"
     ]
    }
   ],
   "source": [
    "history = model.fit(train_dataset, \n",
    "         steps_per_epoch=x_train_scaled.shape[0] // batch_size,\n",
    "         epochs=10,\n",
    "         validation_data=eval_dataset)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-03-09T13:28:07.830689Z",
     "start_time": "2022-03-09T13:28:07.240238Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "157/157 [==============================] - 1s 3ms/step - loss: 0.2578 - accuracy: 0.9318\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[0.25783753395080566, 0.9318000078201294]"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model.evaluate(eval_dataset)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-03-09T13:31:53.697645Z",
     "start_time": "2022-03-09T13:31:53.336106Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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qG5qY8xlxph3jTHbjDG391HmY8aYTcaYjcaYXw+6BiIiclyCwSDFxcUjNojHEmMMxcXFR91LMWDL2BjjBu4BLgFqgLXGmGestZuSykwDvgqcY61tMMaUHlUtRETkuCiIR45j+W8xmJbxQmCbtXa7tbYTeBS4skeZzwL3WGsbAKy1h466JiIiImPUYMJ4PLAnab4mtizZdGC6MebvxpiXjTGXpauCIiIy8uXk5DhdhRNaugZweYBpwGKgClhljJllrW1MLmSMuQG4AaCsrIyVK1em6eMhEAikdX/SNx3r4aHjPDxGw3HOz8+npaXF6Wr0W4dwODwi6jhcgsHgUf27GkwY7wWqk+arYsuS1QCvWGu7gB3GmC1Ew3ltciFr7f3A/QDz58+3ixcvHnRFB7Jy5UrSuT/pm4718NBxHh6j4Thv3rx5RIxUzs3NxVrLl7/8Zf70pz9hjOHOO+9k6dKlbN26lc985jM0NzcTCoW49957WbRoEZ/5zGdYt24dxhg+/elP84UvfMHpr5EWfr+fuXPnDrr8YMJ4LTDNGDOJaAh/HPhEjzK/A64GlhtjSoh2W28fdC1ERCQt/t/vN7JpX3Na93laZR7/+sEZgyr71FNPsX79et58801qa2tZsGAB5513Hr/97W+59NJL+drXvkY4HKatrY3169ezd+9e3n77bQAaGxvTWu8TyYDnjK21IeAW4DlgM/C4tXajMeabxpgrYsWeA+qMMZuAFcC/WGvrhqrSIiIyMr300ktcffXVuN1uysrKOP/881m7di1nnHEGy5cv56677mLDhg3k5uYyefJktm/fzq233sqf//xn8vLynK6+YwZ1ztha+yzwbI9l30iatsAXYy8REXHIYFuww+2cc85h1apV/PGPf+S6667ji1/8Ip/61Kd48803ee655/j5z3/O448/zoMPPuh0VR2he1OLiEjanHvuuTz22GOEw2EOHz7MqlWrWLhwIbt376asrIzPfvazXH/99bz++uvU1tYSiUT4yEc+wt13383rr7/udPUdo9thiohI2nz4wx9mzZo1zJkzB2MM3/ve9ygvL+d3v/sdS5cuxev1kpOTw8MPP8zevXtZtmwZkUgEgH/7t39zuPbOURiLiMhxCwQCQPTuU9///vf5/ve/n7L+mmuu4cYbbzxiu7HcGk6mbmoRERGHKYxFREQcpjAWERFxmMJYRETEYQpjERERhymMRUREHKYwFhERcZjCWEREThihUMjpKgwJhbGIiKTFhz70IebNm8eMGTO4//77Afjzn//MGWecwaJFi7jooouA6A1Cli1bxqxZs5g9ezZPPvkkADk5OYl9PfHEE1x33XUAXHfdddx4442ceeaZfPnLX+bVV1/l7LPPZu7cuSxatIh3330XiD4z+Z//+Z+ZOXMms2fP5qc//SkvvPACH/rQhxL7/etf/8qHP/zhYTgaR0d34BIRGU3+dDsc2JDefZbPgvd/d8BiDz74IEVFRbS3t7NgwQKuvPJKPvvZz7Jq1SpKSkro6uoC4Fvf+hb5+fls2BCtZ0NDw4D7rqmpYfXq1bjdbpqbm3nxxRfxeDw8//zz3HHHHTz55JPcf//97Ny5k/Xr1+PxeKivr6ewsJCbbrqJw4cPM27cOJYvX86nP/3p4zseQ0BhLCIiafGTn/yEp59+GoA9e/Zw//33c9555zFp0iRaWlooKioC4Pnnn+fRRx9NbFdYWDjgvpcsWYLb7QagqamJf/zHf2Tr1q0YYxIh//zzz3PjjTfi8USjLf551157Lb/61a9YtmwZa9as4eGHH07fl04ThbGIyGgyiBbsUFi5ciXPP/88a9asISsri8WLF3P66afzzjvvDHofxpjEdDAYTFmXnZ2dmP7617/OBRdcwNNPP83OnTtZvHhxv/tdtmwZH/zgB/H7/SxZsiQR1iOJzhmLiMhxa2pqorCwkKysLN555x1efvllgsEgq1atYseOHQDU19cDcMkll3DPPfckto13U5eVlbF582YikUiihd3XZ40fPx6Ahx56KLH8kksu4b777ksM8op/XmVlJZWVldx9990sW7YsfV86jRTGIiJy3C677DJCoRCnnnoqt99+O2eddRbjxo3j/vvv56qrrmLRokUsXboUgDvvvJOGhgZmzpzJnDlzWLFiBQDf/e53ufzyy1m0aBEVFRV9ftaXv/xlvvrVrzJ37tyU0dXXX389EyZMYPbs2cyZM4df//rXiXXXXHMN1dXVnHrqqUN0BI6PsdY68sHz58+369atS9v+Vq5cOWBXhaSHjvXw0HEeHqPhOG/evHnEhkxcS0sLubm5jn3+Lbfcwty5c/nMZz4zLJ/X238TY8xr1tr5vZUfeR3nIiIiaTRv3jyys7P54Q9/6HRV+qQwFhGRUe21115zugoD0jljERERhymMRUREHKYwFhERcZjCWERExGEKYxEREYcpjEVEZNglP6Gpp507dzJz5sxhrI3zFMYiIiIO03XGIiKjyL+/+u+8Uz/4hzMMxilFp/CVhV/pt8ztt99OdXU1N998MwB33XUXHo+HFStW0NDQQEdHB9/5zne48sorj+qzg8Egn/vc51i3bh0ej4f/+I//4IILLmDjxo0sW7aMzs5OIpEITz75JJWVlXzsYx+jpqaGcDjM17/+9cQtOEc6hbGIiBy3pUuX8k//9E+JMH788cd57rnnuO2228jLy2Pnzp1cfPHFXHHFFSlPZxrIPffcgzGGDRs28M477/AP//APbNmyhZ///Od8/vOf55prrqGzs5NwOMyzzz5LZWUlf/zjH4HoAyVOFApjEZFRZKAW7FCZO3cuhw4dYt++fRw+fJjCwkLKy8v5whe+wKpVqwDYu3cvBw8epLy8fND7femll7j11lsBOOWUUzjppJPYsmULZ599Nt/+9repqanhqquuYtq0acyaNYsvfelLfOUrX+Hyyy/n3HPPHZLvOhR0zlhERNJiyZIlPPHEEzz22GMsXbqURx55hMOHD/Paa6/x97//nbKysiOeU3ysPvGJT/DMM8+QmZnJBz7wAV544QWmT5/O66+/zqxZs7jzzjv55je/mZbPGg5qGYuISFosXbqUz372s9TW1vK///u/PP7445SWluL1evnLX/7Crl27jnqf5557Lo888ggXXnghW7ZsYffu3Zx88sls376dyZMnc9ttt7F7927eeustTjnlFIqKivjkJz9JQUEBDzzwwBB8y6ExKsLYWsvu5rDT1RARGdNmzJhBS0sL48ePp6KigmuuuYYPfvCDzJo1izlz5nDKKacc9T5vuukmPve5zzFr1iw8Hg8PPfQQGRkZPP744/zyl7/E6/VSXl7OHXfcwdq1a/mXf/kXXC4XXq+Xe++9dwi+5dAYFWH80Oqd3L0myKRTD3PutHFOV0dEZMzasGFDYrqkpIQ1a9YARz7POBAI9LmPiRMn8vbbbwPg9/tZvnz5EWVuv/12br/99pRll156KZdeeulx1d8po+Kc8UfnVVGZ4+Jzv3qdzfubna6OiIjIURkVYZzr9/KFeRnkZHhYtnwt+5vana6SiIgMYMOGDZx++ukprzPPPNPpajliVHRTAxT5XSxfdgZLfr6GZcvX8viNZ5Pn9zpdLRER6cOsWbNYv36909UYEUZFyzju1Io87v3kGWw7FOCmX71OVzjidJVEREQGNKrCGODcaeP4t6tm8dK2Wm5/cgPWWqerJCIi0q9R002dbMn8avY2tvOfz2+lqjCTL1wy3ekqiYiI9GlUhjHA5y+aRk1DOz/+21bGF2bysfnVTldJRESkV6OumzrOGMO/XTWLc6eVcMdTG1i15bDTVRIRkZj+nmc8Fo3aMAbwul387JozmFqaw02PvM6mfboGWUREuoVCIaerAIzibuq4XL+Xh5Yt5MM/+zuffmgtT9+8iIr8TKerJSIyJA585zt0bE7v84wzTj2F8jvu6LdMOp9nHAgEuPLKK2loaKCrq4u77747sd3DDz/MD37wA4wxzJ49m1/+8pccPHiQG2+8ke3btwNw7733UllZyeWXX564k9cPfvADAoEAd911F4sXL+b000/npZde4uqrr2b69OncfffddHZ2UlxczCOPPEJZWRmBQIBbb72VdevWYYzhX//1X2lqauKtt97iP//zPwH4xS9+waZNm/jRj350rIcXGANhDFCe72f5sgUsuVfXIIuIDIV0Ps/Y7/fz9NNPk5eXR21tLWeddRZXXHEFmzZt4u6772b16tWUlJRQX18PwG233cb555/P008/TTgcJhAI0NDQ0O9ndHZ2sm7dOgAaGhp4+eWXMcbwwAMP8L3vfY8f/vCHfOtb3yI/Pz9xi8+Ghga8Xi/f/va3+f73v4/X62X58uXcd999x3v4BhfGxpjLgB8DbuABa+13+yj3EeAJYIG1dt1x1y6NTinP495PzuO65a9y069e58HrFuDzjOpeehEZgwZqwQ6VdD7P2FrLHXfcwapVq3C5XIntXnjhBZYsWUJJSQkARUVFALzwwgs8/PDDALjdbvLz8wcM46VLlyama2pqWLp0Kfv376ezs5NJkyYB8Pzzz/Poo48myhUWFgJw4YUX8oc//IFTTz2Vrq4uZs2adTSHqlcDppExxg3cA7wfOA242hhzWi/lcoHPA68cd62GyPumlfDdj8zmpW21fPUpXYMsIpJO6XqecfJ269evP6bnIHs8HiKR7hs/9dw+Ozs7MX3rrbdyyy23sGHDBu67774BP+v666/noYceYvny5Sxbtuyo6tWXwTQNFwLbrLXbrbWdwKNAb53+3wL+HUjP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\n",
      "text/plain": [
       "<Figure size 576x360 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "def plot_learning_curves(history):\n",
    "    pd.DataFrame(history.history).plot(figsize=(8, 5))\n",
    "    plt.grid(True)\n",
    "    plt.gca().set_ylim(0, 1)\n",
    "    plt.show()\n",
    "    \n",
    "plot_learning_curves(history)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.6"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
